home *** CD-ROM | disk | FTP | other *** search
- ;;; CMPFUN Library functions.
- ;;;
- ;; (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
- ;; Copying of this file is authorized to users who have executed the true and
- ;; proper "License Agreement for Kyoto Common LISP" with SIGLISP.
-
- (in-package 'compiler)
-
- (si:putprop 'princ 'c1princ 'c1)
- (si:putprop 'princ 'c2princ 'c2)
- (si:putprop 'terpri 'c1terpri 'c1)
-
- (si:putprop 'apply 'c1apply 'c1)
- (si:putprop 'apply 'c2apply 'c2)
- (si:putprop 'apply-optimize 'c2apply-optimize 'c2)
- (si:putprop 'funcall 'c1funcall 'c1)
-
- (si:putprop 'rplaca 'c1rplaca 'c1)
- (si:putprop 'rplaca 'c2rplaca 'c2)
- (si:putprop 'rplacd 'c1rplacd 'c1)
- (si:putprop 'rplacd 'c2rplacd 'c2)
-
- (si:putprop 'si::memq 'c1memq 'c1)
- (si:putprop 'member 'c1member 'c1)
- (si:putprop 'member!2 'c2member!2 'c2)
- (si:putprop 'assoc 'c1assoc 'c1)
- (si:putprop 'assoc!2 'c2assoc!2 'c2)
- (si:putprop 'get 'c1get 'c1)
- (si:putprop 'get 'c2get 'c2)
-
- (si:putprop 'list '(c1list-condition . c1list) 'c1conditional)
- (si:putprop 'list* '(c1list-condition . c1list*) 'c1conditional)
- (si:putprop 'nth '(c1nth-condition . c1nth) 'c1conditional)
- (si:putprop 'nthcdr '(c1nthcdr-condition . c1nthcdr) 'c1conditional)
- (si:putprop 'si:rplaca-nthcdr 'c1rplaca-nthcdr 'c1)
- (si:putprop 'rplaca-nthcdr-immediate 'c2rplaca-nthcdr-immediate 'c2)
- (si:putprop 'si:list-nth 'c1list-nth 'c1)
- (si:putprop 'list-nth-immediate 'c2list-nth-immediate 'c2)
-
- (defvar *princ-string-limit* 80)
-
- (defun c1princ (args &aux stream (info (make-info)))
- (when (endp args) (too-few-args 'princ 1 0))
- (unless (or (endp (cdr args)) (endp (cddr args)))
- (too-many-args 'princ 2 (length args)))
- (setq stream (if (endp (cdr args))
- (c1nil)
- (c1expr* (cadr args) info)))
- (if (and (or (and (stringp (car args))
- (<= (length (car args)) *princ-string-limit*))
- (characterp (car args)))
- (or (endp (cdr args))
- (and (eq (car stream) 'var)
- (member (var-kind (caaddr stream)) '(GLOBAL SPECIAL)))))
- (list 'princ info (car args)
- (if (endp (cdr args)) nil (var-loc (caaddr stream)))
- stream)
- (list 'call-global info 'princ
- (list (c1expr* (car args) info) stream))))
-
- (defun c2princ (string vv-index stream)
- (cond ((eq *value-to-go* 'trash)
- (cond ((characterp string)
- (wt-nl "princ_char(" (char-code string))
- (if (null vv-index) (wt ",Cnil") (wt ",VV[" vv-index "]"))
- (wt ");"))
- ((= (length string) 1)
- (wt-nl "princ_char(" (char-code (aref string 0)))
- (if (null vv-index) (wt ",Cnil") (wt ",VV[" vv-index "]"))
- (wt ");"))
- (t
- (wt-nl "princ_str(\"")
- (dotimes** (n (length string))
- (let ((char (schar string n)))
- (cond ((char= char #\\) (wt "\\\\"))
- ((char= char #\") (wt "\\\""))
- ((char= char #\Newline) (wt "\\n"))
- (t (wt char)))))
- (wt "\",")
- (if (null vv-index) (wt "Cnil") (wt "VV[" vv-index "]"))
- (wt ");")))
- (unwind-exit nil))
- ((eql string #\Newline) (c2call-global 'terpri (list stream) nil t))
- (t (c2call-global
- 'princ
- (list (list 'LOCATION
- (make-info :type
- (if (characterp string) 'character 'string))
- (list 'VV (add-object string)))
- stream) nil t))))
-
- (defun c1terpri (args &aux stream (info (make-info)))
- (unless (or (endp args) (endp (cdr args)))
- (too-many-args 'terpri 1 (length args)))
- (setq stream (if (endp args)
- (c1nil)
- (c1expr* (car args) info)))
- (if (or (endp args)
- (and (eq (car stream) 'var)
- (member (var-kind (caaddr stream)) '(GLOBAL SPECIAL))))
- (list 'princ info #\Newline
- (if (endp args) nil (var-loc (caaddr stream)))
- stream)
- (list 'call-global info 'terpri (list stream))))
-
- (defun c1apply (args &aux info)
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'apply 2 (length args)))
- (let ((funob (c1funob (car args))))
- (setq info (copy-info (cadr funob)))
- (setq args (c1args (cdr args) info))
- (cond ((eq (car funob) 'call-lambda)
- (let* ((lambda-expr (caddr funob))
- (lambda-list (caddr lambda-expr)))
- (declare (object lambda-expr lambda-list))
- (if (and (null (cadr lambda-list)) ; No optional
- (null (cadddr lambda-list))) ; No keyword
- (c1apply-optimize info
- (car lambda-list)
- (caddr lambda-list)
- (car (cddddr lambda-expr))
- args)
- (list 'apply info funob args))))
- (t (list 'apply info funob args))))
- )
-
- (defun c2apply (funob args &aux (*vs* *vs*) loc)
- (setq loc (save-funob funob))
- (let ((*vs* *vs*) (base *vs*) (last-arg (list 'CVAR (next-cvar))))
- (do ((l args (cdr l)))
- ((endp (cdr l))
- (wt-nl "{object " last-arg ";")
- (let ((*value-to-go* last-arg)) (c2expr* (car l))))
- (declare (object l))
- (let ((*value-to-go* (list 'vs (vs-push)))) (c2expr* (car l))))
- (wt-nl " vs_top=base+" *vs* ";")
- (base-used)
- (cond (*safe-compile*
- (wt-nl " while(!endp(" last-arg "))")
- (wt-nl " {vs_push(car(" last-arg "));")
- (wt last-arg "=cdr(" last-arg ");}"))
- (t
- (wt-nl " while(" last-arg "!=Cnil)")
- (wt-nl " {vs_push((" last-arg ")->c.c_car);")
- (wt last-arg "=(" last-arg ")->c.c_cdr;}")))
- (wt-nl "vs_base=base+" base ";}")
- (base-used))
- (c2funcall funob 'args-pushed loc)
- )
-
- (defun c1apply-optimize (info requireds rest body args
- &aux (vl nil) (fl nil))
- (do ()
- ((or (endp (cdr args)) (endp requireds)))
- (push (pop requireds) vl)
- (push (pop args) fl))
-
- (cond ((cdr args) ;;; REQUIREDS is NIL.
- (cmpck (null rest)
- "APPLY passes too many arguments to LAMBDA expression.")
- (push rest vl)
- (push (list 'call-global info 'list* args) fl)
- (list 'let info (reverse vl) (reverse fl) body))
- (requireds ;;; ARGS is singleton.
- (let ((temp (make-var :kind 'LEXICAL :ref t)))
- (push temp vl)
- (push (car args) fl)
- (list 'let info (reverse vl) (reverse fl)
- (list 'apply-optimize
- (cadr body) temp requireds rest body))))
- (rest (push rest vl)
- (push (car args) fl)
- (list 'let info (reverse vl) (reverse fl) body))
- (t
- (let ((temp (make-var :kind 'LEXICAL :ref t)))
- (push temp vl)
- (push (car args) fl)
- (list 'let info (reverse vl) (reverse fl)
- (list 'apply-optimize
- (cadr body) temp requireds rest body))))
- )
- )
-
- (defun c2apply-optimize (temp requireds rest body
- &aux (*unwind-exit* *unwind-exit*) (*vs* *vs*)
- (*clink* *clink*) (*ccb-vs* *ccb-vs*))
- (when (or *safe-compile* *compiler-check-args*)
- (wt-nl (if rest "ck_larg_at_least" "ck_larg_exactly")
- "(" (length requireds) ",")
- (wt-var temp nil)
- (wt ");"))
-
- (dolist** (v requireds) (setf (var-ref v) (vs-push)))
- (when rest (setf (var-ref rest) (vs-push)))
-
- (do ((n 0 (1+ n))
- (vl requireds (cdr vl)))
- ((endp vl)
- (when rest
- (wt-nl) (wt-vs (var-ref rest)) (wt "= ")
- (dotimes** (i n) (wt "("))
- (wt-var temp nil)
- (dotimes** (i n) (wt-nl ")->c.c_cdr"))
- (wt ";")))
- (declare (fixnum n) (object vl))
- (wt-nl) (wt-vs (var-ref (car vl))) (wt "=(")
- (dotimes** (i n) (wt "("))
- (wt-var temp nil)
- (dotimes** (i n) (wt-nl ")->c.c_cdr"))
- (wt ")->c.c_car;"))
-
- (dolist** (var requireds) (c2bind var))
- (when rest (c2bind rest))
-
- (c2expr body)
- )
-
- (defun c1funcall (args &aux funob (info (make-info)))
- (when (endp args) (too-few-args 'funcall 1 0))
- (setq funob (c1funob (car args)))
- (add-info info (cadr funob))
- (list 'funcall info funob (c1args (cdr args) info))
- )
-
- (defun c1rplaca (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'rplaca 2 (length args)))
- (unless (endp (cddr args))
- (too-many-args 'rplaca 2 (length args)))
- (setq args (c1args args info))
- (list 'rplaca info args))
-
- (defun c2rplaca (args &aux (*vs* *vs*) (*inline-blocks* 0))
- (setq args (inline-args args '(t t)))
- (safe-compile
- (wt-nl "if(type_of(" (car args) ")!=t_cons)"
- "FEwrong_type_argument(Scons," (car args) ");"))
- (wt-nl "(" (car args) ")->c.c_car = " (cadr args) ";")
- (unwind-exit (car args))
- (close-inline-blocks)
- )
-
- (defun c1rplacd (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'rplacd 2 (length args)))
- (when (not (endp (cddr args)))
- (too-many-args 'rplacd 2 (length args)))
- (setq args (c1args args info))
- (list 'rplacd info args))
-
- (defun c2rplacd (args &aux (*vs* *vs*) (*inline-blocks* 0))
- (setq args (inline-args args '(t t)))
- (safe-compile
- (wt-nl "if(type_of(" (car args) ")!=t_cons)"
- "FEwrong_type_argument(Scons," (car args) ");"))
- (wt-nl "(" (car args) ")->c.c_cdr = " (cadr args) ";")
- (unwind-exit (car args))
- (close-inline-blocks)
- )
-
- (defun c1memq (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'si::memq 2 (length args)))
- (unless (endp (cddr args))
- (too-many-args 'si::memq 2 (length args)))
- (list 'member!2 info 'eq (c1args (list (car args) (cadr args)) info)))
-
- (defun c1member (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'member 2 (length args)))
- (cond ((endp (cddr args))
- (list 'member!2 info 'eql (c1args args info)))
- ((and (eq (caddr args) :test)
- (or (equal (cdddr args) '((quote eq)))
- (equal (cdddr args) '((function eq)))))
- (list 'member!2 info 'eq
- (c1args (list (car args) (cadr args)) info)))
- (t
- (list 'call-global info 'member (c1args args info)))))
-
- (defun c2member!2 (fun args
- &aux (*vs* *vs*) (*inline-blocks* 0) (l (next-cvar)))
- (setq args (inline-args args '(t t)))
- (wt-nl "{object x= " (car args) ",V" l "= " (cadr args) ";")
- (if *safe-compile*
- (wt-nl "while(!endp(V" l "))")
- (wt-nl "while(V" l "!=Cnil)"))
- (if (eq fun 'eq)
- (wt-nl "if(x==(V" l "->c.c_car)){")
- (wt-nl "if(eql(x,V" l "->c.c_car)){"))
- (if (and (consp *value-to-go*)
- (or (eq (car *value-to-go*) 'JUMP-TRUE)
- (eq (car *value-to-go*) 'JUMP-FALSE)))
- (unwind-exit t 'JUMP)
- (unwind-exit (list 'CVAR l) 'JUMP))
- (wt-nl "}else V" l "=V" l "->c.c_cdr;")
- (unwind-exit nil)
- (wt "}")
- (close-inline-blocks)
- )
-
- (defun c1assoc (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'assoc 2 (length args)))
- (cond ((endp (cddr args))
- (list 'assoc!2 info 'eql (c1args args info)))
- ((and (eq (caddr args) ':test)
- (or (equal (cdddr args) '((quote eq)))
- (equal (cdddr args) '((function eq)))))
- (list 'assoc!2 info 'eq (c1args (list (car args) (cadr args)) info)))
- (t
- (list 'call-global info 'assoc (c1args args info)))))
-
- (defun c2assoc!2 (fun args
- &aux (*vs* *vs*) (*inline-blocks* 0) (al (next-cvar)))
- (setq args (inline-args args '(t t)))
- (wt-nl "{object x= " (car args) ",V" al "= " (cadr args) ";")
- (cond (*safe-compile*
- (wt-nl "while(!endp(V" al "))")
- (if (eq fun 'eq)
- (wt-nl "if(x==car(V" al "->c.c_car)){")
- (wt-nl "if(eql(x,car(V" al "->c.c_car))){")))
- (t
- (wt-nl "while(V" al "!=Cnil)")
- (if (eq fun 'eq)
- (wt-nl "if(x==(V" al "->c.c_car->c.c_car)){")
- (wt-nl "if(eql(x,V" al "->c.c_car->c.c_car)){"))))
- (if (and (consp *value-to-go*)
- (or (eq (car *value-to-go*) 'jump-true)
- (eq (car *value-to-go*) 'jump-false)))
- (unwind-exit t 'jump)
- (unwind-exit (list 'CAR al) 'jump))
- (wt-nl "}else V" al "=V" al "->c.c_cdr;")
- (unwind-exit nil)
- (wt "}")
- (close-inline-blocks)
- )
-
- (defun c1get (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'get 2 (length args)))
- (when (and (not (endp (cddr args))) (not (endp (cdddr args))))
- (too-many-args 'get 3 (length args)))
- (list 'get info (c1args args info)))
-
- (defun c2get (args)
- (if *safe-compile*
- (c2call-global 'get args nil t)
- (let ((*vs* *vs*) (*inline-blocks* 0) (pl (next-cvar)))
- (setq args (inline-args args (if (cddr args) '(t t t) '(t t))))
- (wt-nl "{object V" pl" =(" (car args) ")->s.s_plist;")
- (wt-nl " object ind= " (cadr args) ";")
- (wt-nl "while(V" pl "!=Cnil){")
- (wt-nl "if(V" pl "->c.c_car==ind){")
- (unwind-exit (list 'CADR pl) 'jump)
- (wt-nl "}else V" pl "=V" pl "->c.c_cdr->c.c_cdr;}")
- (unwind-exit (if (cddr args) (caddr args) nil))
- (wt "}")
- (close-inline-blocks)))
- )
-
- (defun c1list-condition (args) (declare (ignore args)) (= *space* 0))
-
- (defun c1list (args)
- (do ((l (reverse args) (cdr l))
- (form nil))
- ((endp l) (c1expr form))
- (setq form (list 'cons (car l) form))))
-
- (defun c1list* (args)
- (when (endp args) (too-few-args 'list* 1 0))
- (setq args (reverse args))
- (do ((l (cdr args) (cdr l))
- (form (car args)))
- ((endp l) (c1expr form))
- (setq form (list 'cons (car l) form))))
-
- (defun c1nth-condition (args)
- (and (not (endp args))
- (not (endp (cdr args)))
- (endp (cddr args))
- (numberp (car args))
- (<= 0 (car args) 7)))
-
- (defun c1nth (args)
- (c1expr (case (car args)
- (0 (cons 'car (cdr args)))
- (1 (cons 'cadr (cdr args)))
- (2 (cons 'caddr (cdr args)))
- (3 (cons 'cadddr (cdr args)))
- (4 (list 'car (cons 'cddddr (cdr args))))
- (5 (list 'cadr (cons 'cddddr (cdr args))))
- (6 (list 'caddr (cons 'cddddr (cdr args))))
- (7 (list 'cadddr (cons 'cddddr (cdr args))))
- )))
-
- (defun c1nthcdr-condition (args)
- (and (not (endp args))
- (not (endp (cdr args)))
- (endp (cddr args))
- (numberp (car args))
- (<= 0 (car args) 7)))
-
- (defun c1nthcdr (args)
- (c1expr (case (car args)
- (0 (cadr args))
- (1 (cons 'cdr (cdr args)))
- (2 (cons 'cddr (cdr args)))
- (3 (cons 'cdddr (cdr args)))
- (4 (cons 'cddddr (cdr args)))
- (5 (list 'cdr (cons 'cddddr (cdr args))))
- (6 (list 'cddr (cons 'cddddr (cdr args))))
- (7 (list 'cdddr (cons 'cddddr (cdr args))))
- )))
-
- (defun c1rplaca-nthcdr (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)) (endp (cddr args)))
- (too-few-args 'si:rplaca-nthcdr 3 (length args)))
- (unless (endp (cdddr args))
- (too-few-args 'si:rplaca-nthcdr 3 (length args)))
- (if (and (numberp (cadr args)) (<= 0 (cadr args) 10))
- (list 'rplaca-nthcdr-immediate info
- (cadr args)
- (c1args (list (car args) (caddr args)) info))
- (list 'call-global info 'si:rplaca-nthcdr (c1args args info))))
-
- (defun c2rplaca-nthcdr-immediate (index args
- &aux (*vs* *vs*) (*inline-blocks* 0))
- (setq args (inline-args args '(t t t)))
- (if *safe-compile*
- (progn
- (wt-nl "{object l= ")
- (dotimes** (i index) (wt "cdr("))
- (wt (car args))
- (dotimes** (i index) (wt ")"))
- (wt ";")
- (wt-nl "if(type_of(l)!=t_cons)FEwrong_type_argument(Scons,l);")
- (wt-nl "l->c.c_car= " (cadr args) ";}")
- )
- (progn
- (wt-nl (car args))
- (dotimes** (i index) (wt-nl "->c.c_cdr"))
- (wt-nl "->c.c_car= " (cadr args) ";")))
- (unwind-exit (cadr args))
- (close-inline-blocks)
- )
-
- (defun c1list-nth (args &aux (info (make-info)))
- (when (or (endp args) (endp (cdr args)))
- (too-few-args 'si:rplaca-nthcdr 2 (length args)))
- (unless (endp (cddr args))
- (too-few-args 'si:rplaca-nthcdr 2 (length args)))
- (if (and (numberp (car args)) (<= 0 (car args) 10))
- (list 'list-nth-immediate info
- (car args)
- (c1args (list (cadr args)) info))
- (list 'call-global info 'si:list-nth (c1args args info))))
-
- (defun c2list-nth-immediate (index args &aux (l (next-cvar))
- (*vs* *vs*) (*inline-blocks* 0))
- (setq args (inline-args args '(t t)))
- (wt-nl "{object V" l "= ")
- (if *safe-compile*
- (progn
- (dotimes** (i index) (wt "cdr("))
- (wt (car args))
- (dotimes** (i index) (wt ")"))
- (wt ";")
- (wt-nl "if(type_of(V" l ")!=t_cons)")
- (wt-nl " FEwrong_type_argument(Scons,V" l ");")
- )
- (progn
- (wt-nl (car args))
- (dotimes** (i index) (wt-nl "->c.c_cdr"))
- (wt ";")))
- (unwind-exit (list 'CAR l))
- (wt "}")
- (close-inline-blocks)
- )
-
-
-